package edu.vt.cbil.dataset;

import edu.vt.cbil.util.BioToolbox;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Created by Justin on 2014/12/30.
 */
public class BioSample implements Serializable {


    private static final long serialVersionUID = -1891374646810635981L;
    private final double RobustStdMultiplier = 2.5;
    public double attenuationM;
    public double fourfoldPeak;
    private String sampleId;
    private ArrayList<Chromosome> sample;

    public BioSample(String sampleId) {
        this.sampleId = sampleId;

        // U 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 U X Y MT
        sample = new ArrayList<Chromosome>();
        for (int i = 0; i < 27; i++) {
            sample.add(new Chromosome());
        }
    }

//    public void finalize() throws Throwable {
//        super.finalize();
//        sample = null;
//    }

    public String getSampleId() {
        return sampleId;
    }

    public ArrayList<Chromosome> getAllChromosomes() {
        return sample;
    }

    public Chromosome getChromosome(int chrId) {
        return sample.get(chrId);
    }

    public ProbeSet getProbeSet(long pos) {
        int[] chr_id = BioToolbox.getChrIdAndStartPosition(pos);

        return sample.get(chr_id[0]).probes.get(pos);
    }

    public ProbeSet getProbeSet(int chrId, long pos) {
        return sample.get(chrId).probes.get(pos);
    }

    public Map<Long, ProbeSet> getAllProbeSets(int chrId) {
        return sample.get(chrId).probes;
    }

    public Set<Segment> getAllSegments(int chrId) {
        return sample.get(chrId).segments;
    }

    public void modifySegments(int chrId, Set<Segment> inputSegments) {
        sample.get(chrId).segments = inputSegments;
    }

    public void setReferenceSegmentForEachProbSet() {
        for (int i = 0; i < 27; i++) {
            Set<Segment> segSet = sample.get(i).segments;
            Map<Long, ProbeSet> psMap = sample.get(i).probes;
            if (segSet.size() > 0) {
                for (Segment aSeg : segSet) {
                    for (Long id : aSeg.Loci.keySet()) {
                        ProbeSet ps = psMap.get(id);
                        ps.data.parent_segment = aSeg;
                    }
                }
            }
        }
    }

    public void refreshValidProbes() {

        for (int i = 0; i < 27; i++) {
            Set<Segment> segSet = sample.get(i).segments;
            Map<Long, ProbeSet> psMap = sample.get(i).probes;

            if (segSet.size() > 0) {
                for (Segment aSeg : segSet) {
                    for (Long id : aSeg.Loci.keySet()) {
                        ProbeSet ps = psMap.get(id);
                        aSeg.Loci.put(ps.Loci, ps.data.CopyNumberHalf);
                    }
                    aSeg.updateCharacters();
//
//                    double cnMean = aSeg.robustMeanHalfCopyNumber;
//                    double cnMultiStd = RobustStdMultiplier * aSeg.robustStdHalfCopyNumber;
//                    double lower = cnMean - cnMultiStd;
//                    double upper = cnMean + cnMultiStd;
//                    for (Long id : aSeg.Loci.keySet()){
//                        ProbeSet ps = psMap.get(id);
//                        if (ps.data.CopyNumberHalf>upper || ps.data.CopyNumberHalf<lower){
//                            ps.data.Is_Valid = false;
//                            aSeg.Loci.remove(ps);
//                        }
//                    }
                }
            }
        }
    }

    public void clear() {
        for (int i = 0; i < 27; i++) {
            sample.get(i).clear();
        }
    }

    public int getProbeSetCount(List<Short> seelectedChr) {
        int sum = 0;
        for (short i : seelectedChr) {
            sum += sample.get(i).getPorbeSetCount();
        }
        return sum;
    }
}
